﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace KuPeiXun.Utility
{
	/// <summary>
    /// 异常处理模块 
    /// Create: ShalJuen 2010/10/16
	/// </summary>
    /// <example> 代码调用实例 
    /// <code>
    /// // 记录包含发生对象的异常消息
    /// try
    /// {
    ///     ...
    /// }
    /// catch (Exception ex)
    /// { 
    ///     new ZeroWire.Exception.AoneSoftException(ex, this);
    /// }
    /// 
    /// // 记录自定义的异常消息
    /// try
    /// {
    ///     ...
    /// }
    /// catch (Exception ex)
    /// { 
    ///     new ZeroWire.Exception.AoneSoftException("custom message!");
    /// }
    /// </code>
    /// </example>
    /// <remarks>
    /// </remarks>
	public class LogHepler : System.Exception
	{
        // 主程序文件的子文件夹(如果缺省不赋值,则保存至执行文件同级目录)
        public static string logVirtualPath = "Log";
		// 定义 LOG 存储路径及文件名
		private string ConfigTextLogName = System.DateTime.Now.ToString("yyyyMMdd") + ".Log";
        /// <summary>
        /// 异常处理，记录自定义错误消息
        /// </summary>
        /// <param name="ThrowMessage">自定义错误内容</param>
		public LogHepler(string ThrowMessage)
		{
			new LogHepler(null,null,ThrowMessage,string.Empty);
		}

        /// <summary>
        /// 异常处理，记录程序错误信息
        /// </summary>
        /// <param name="ex">错误消息</param>
		public LogHepler(System.Exception ex)
		{
			new LogHepler(ex,null,null,string.Empty);
		}

		/// <summary>
        /// 异常处理,指明发生对象
		/// </summary>
		/// <param name="ex">错误消息</param>
        /// <param name="caller">指明发生对象,例:this 或自定义类名</param>
        public LogHepler(System.Exception ex, object caller)
		{
			new LogHepler(ex,caller,null,string.Empty);
		}

        /// <summary>
        /// 异常处理,指明发生对象
        /// </summary>
        /// <param name="ex">错误消息</param>
        /// <param name="caller">指明发生对象,例:this 或自定义类名</param>
        /// <param name="Message">自定义错误信息</param>
        public LogHepler(System.Exception ex, object caller, string Message)
        {
            new LogHepler(ex, caller, Message, string.Empty);
        }

        /// <summary>
        /// 异常处理,并保存异常错误信息至指定目录
        /// </summary>
        /// <param name="ex">错误消息</param>
        /// <param name="caller">指明发生对象,例:this 或自定义类名</param>
        /// <param name="Message">自定义错误信息</param>
        /// <param name="Developer">编写者</param>
        public LogHepler(System.Exception ex, object caller, string Message, string Developer)
		{
			string ConfigTextLogPath = AppPath()  + @"\" + logVirtualPath;
            string ExceptionMemo = string.Empty ;

            // 是否存在文件夹
            if (!Directory.Exists(ConfigTextLogPath))
                Directory.CreateDirectory(ConfigTextLogPath);
            ConfigTextLogPath = ConfigTextLogPath + @"\" + ConfigTextLogName;
            ExceptionMemo = AllFormat2Log(System.DateTime.Now, Developer, caller, ex, Message);

            TextWriter writeFile = new StreamWriter(ConfigTextLogPath, true,
                    System.Text.Encoding.UTF8); 
			try
			{
                writeFile.Write(ExceptionMemo);
                writeFile.Close();
			}
            catch (System.Exception)
			{

			}
			finally
			{
                writeFile.Close();
			}
		}

        /// <summary>
        /// 将所有内容信息转为固定格式log
        /// </summary>
        /// <example>
        /// 日志格式范例
        /// <code>
        /// //日期：2009-06-17 15:33:34 
        /// //程序：
        /// //版本：1.0.0.0 
        /// //类名：AoneSoftException.Form1
        /// //类型：IndexOutOfRangeException
        /// //描述：下标溢出
        /// //跟踪：位于 AoneSoftException.Form1.button1_Click()
        /// //备注：(Developer) 自定义Message
        /// </code>
        /// </example>
        /// <returns></returns>
        private string AllFormat2Log(DateTime senderDateTime, string senderDeveloper, object senderCaller,
            System.Exception senderException, string senderErrorMessage)
        {
            StringBuilder myBuilder = new StringBuilder();
            myBuilder.Append("日期：" + senderDateTime.ToString("yyyy-MM-dd HH:mm:ss"));
            myBuilder.Append((char)9);
            myBuilder.Append("\r\n");
            myBuilder.Append("程序：" + System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            myBuilder.Append((char)9);
            myBuilder.Append("\r\n");
            myBuilder.Append("版本：" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(4));
            myBuilder.Append((char)9);
            myBuilder.Append("\r\n");
            if (senderCaller != null)
            {
                if (senderCaller.GetType().FullName != "System.String")
                    myBuilder.Append("类名：" + senderCaller.GetType().FullName.ToString());
                else
                    myBuilder.Append("类名：" + senderCaller.ToString());
                myBuilder.Append((char)9);
                myBuilder.Append("\r\n");
                
            }
            if (senderException != null)
            {
                myBuilder.Append("类型：" + senderException.GetType().Name);
                myBuilder.Append((char)9);
                myBuilder.Append("\r\n");
                myBuilder.Append("描述：" + senderException.Message);
                myBuilder.Append((char)9);
                myBuilder.Append("\r\n");
                myBuilder.Append("跟踪：" + senderException.StackTrace); // .Substring(0,senderException.StackTrace.IndexOf("\r\n"))
                myBuilder.Append((char)9);
                myBuilder.Append("\r\n");
                
            }
            if (senderDeveloper.Trim() != string.Empty)
                myBuilder.Append("备注：(" + senderDeveloper + ") " + senderErrorMessage);
            else
                myBuilder.Append("备注：" + senderErrorMessage);
            myBuilder.Append((char)32);
            myBuilder.Append("\r\n\r\n");
            return myBuilder.ToString();
        }


		#region 取得程序路径
        /// <summary>
        /// 获取程序路径
        /// </summary>
        /// <returns></returns>
		private string AppPath()
		{
            //string AppPath = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase.
            //    Substring(0, System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase.LastIndexOf("/"));
            //AppPath = AppPath.Substring(8,AppPath.Length - 8);
            //AppPath = AppPath.Replace('/', '\\');     //存放在bin目录下
            string AppPath = AppDomain.CurrentDomain.BaseDirectory;     //存放在根目录下
			return AppPath;
		}
		#endregion

	}
}

